// +build debugcharts
package galaxy

import (
	"fmt"
	"os"
	"path"
	"path/filepath"

	"gddgame.cc/galaxy/utils"
	"gddgame.cc/galaxy/utils/def"
	flag "gddgame.cc/galaxy/utils/mflag"

	//_ "github.com/mkevac/debugcharts"
	"github.com/sirupsen/logrus"
)

const (
	DefaultConfig = "config"
)

type Flags struct {
	FlagSet *flag.FlagSet

	Debug    bool
	Test     bool
	PidFile  string
	LogLevel string
	//Perform        bool
	ConfigFileName string
	Daemon         bool

	LogName string

	version bool
	help    bool

	subject     string
	description string
	versionInfo string
}

func (f *Flags) init() {
	f.FlagSet = new(flag.FlagSet)
	cmd := f.FlagSet
	cmd.BoolVar(&flags.Debug, []string{"D", "-debug"}, false, "Enable debug mode")
	cmd.BoolVar(&flags.Test, []string{"t", "-test"}, false, "Test server start and exit")
	cmd.StringVar(&flags.PidFile, []string{"p", "-pid"}, "", "Server pid file")
	cmd.StringVar(&flags.LogLevel, []string{"l", "-log-level"}, "info", "Set the logging level")
	//cmd.BoolVar(&flags.Perform, []string{"P", "-perform"}, false, "Enable ")
	cmd.StringVar(&flags.ConfigFileName, []string{"-config"}, "", "Location of config file：json/yaml")
	cmd.BoolVar(&flags.Daemon, []string{"-daemon"}, false, "Run Daemon mode")

	flag.BoolVar(&flags.version, []string{"v", "-version"}, false, "Show Current Version")
	flag.BoolVar(&flags.help, []string{"h", "-help"}, false, "Print usage")
}

func (f *Flags) usage() {
	fmt.Println(f.subject + " " + VERSION)
	fmt.Println("Usage:	" + filepath.Base(os.Args[0]) + " [OPTIONS]")
	fmt.Println("")
	fmt.Println(f.description)
	fmt.Println("Options:")

	flag.CommandLine.SetOutput(os.Stdout)
	flag.PrintDefaults()
}

func (f *Flags) execute() error {
	if err := flag.Merge(flag.CommandLine, f.FlagSet); err != nil {
		return err
	}
	flag.Parse()

	if f.version {
		fmt.Println(f.versionInfo)
		os.Exit(0)
		return nil
	}
	if f.help {
		f.usage()
		os.Exit(0)
		return nil
	}
	if f.LogLevel != "" {
		if err := f.SetLogLevel(f.LogLevel); err != nil {
			return err
		}
	} else {
		if err := f.SetLogLevel("info"); err != nil {
			return err
		}
	}

	if f.Debug {
		f.SetDebug()
	}

	if f.ConfigFileName == "" {
		logger.Debugln("config not define, use default file: " + DefaultConfig + "(.json|.yaml)")
		if _, err := os.Stat(DefaultConfig + ".json"); err == nil {
			f.ConfigFileName = DefaultConfig + ".json"
		} else if _, err := os.Stat(DefaultConfig + ".yaml"); err == nil {
			f.ConfigFileName = DefaultConfig + ".yaml"
		} else {
			return fmt.Errorf("default config not exist, please define config")
		}
	}
	file := ""
	if path.IsAbs(f.ConfigFileName) {
		file = f.ConfigFileName
	} else {
		currentPath, _ := os.Getwd()
		file = path.Join(currentPath, f.ConfigFileName)
	}
	if err := config.LoadConfig(file); err != nil {
		if os.IsNotExist(err) {
			return fmt.Errorf("Config file is not exist:%s", file)
		} else {
			return fmt.Errorf("Unable to parse config file: %s\n%s", f.ConfigFileName, err)
		}
	}
	if err := f.SetConfig(config.data); err != nil {
		return err
	}

	return nil
}

func (f *Flags) Logger() def.Logger {
	return logger
}

func (f *Flags) SetTest() {
	if err := os.Setenv("TEST", "1"); err != nil {
		logger.Warn(err)
	}
	f.Test = true
}

func (f *Flags) SetDaemon() {
	if err := os.Setenv("DAEMON", "1"); err != nil {
		logger.Warn(err)
	}
	f.Daemon = true
}

func (f *Flags) SetPidFile(pidFile string) {
	f.PidFile = pidFile
}

func (f *Flags) SetDebug() {
	if err := os.Setenv("DEBUG", "1"); err != nil {
		logger.Warn(err)
	}
	f.Debug = true
	rl.logger.SetLevel(logrus.DebugLevel)
}

func (f *Flags) SetLogLevel(level string) error {
	lvl, err := logrus.ParseLevel(level)
	if err != nil {
		return fmt.Errorf("Unable to parse logging level: %s %s\n", level, err.Error())
	}
	rl.logger.SetLevel(lvl)
	return nil
}

func (f *Flags) SetConfig(data map[string]interface{}) error {
	config.data = data
	debug := config.Read("debug")
	if debug != nil {
		d := utils.ToBool(debug)
		if d {
			f.SetDebug()
		}
	}
	log := config.Read("log")
	if log != nil {
		f.LogName = log.(string)
	}
	return nil
}
